/**
 * by sunny 2015-12-08
 */
package uf.audit.util;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.google.common.collect.Lists;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.Model;

import uf.audit.controller.UFBaseController;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class AuditEntities {

	private List<Class<? extends UFBaseController>> excludeClasses = Lists.newArrayList();
	private boolean includeAllJarsInLib;
	private List<String> includeJars = Lists.newArrayList();
	private ActiveRecordPlugin arp;

	protected final Logger log = Logger.getLogger(getClass());

	public AuditEntities(ActiveRecordPlugin arp) {
		this.arp = arp;
	}

	public AuditEntities addExcludeClasses(Class<? extends UFBaseController>[] clazzes) {
		if (clazzes != null) {
			for (Class clazz : clazzes) {
				this.excludeClasses.add(clazz);
			}
		}
		return this;
	}

	public AuditEntities addExcludeClasses(List<Class<? extends UFBaseController>> clazzes) {
		this.excludeClasses.addAll(clazzes);
		return this;
	}

	public AuditEntities addJars(String... jars) {
		if (jars != null) {
			for (String jar : jars) {
				this.includeJars.add(jar);
			}
		}
		return this;
	}

	public void config() throws SQLException {
		final List<Class<? extends Model>> modelClasses = new ArrayList<Class<? extends Model>>();

		ClassSearcher scan = new ClassSearcher();
		scan.addType(Model.class);
		scan.setScanPaths("uf.audit.db");
		scan.scanClasses(new IScanInvoke() {

			public void invoke(ClassSearcher scan, Class clazz) {
				// TODO Auto-generated method stub
				modelClasses.add(clazz);
				if (log.isDebugEnabled()) {
					log.debug(clazz.getName() + " is loaded.");
				}
			}

		});

		Table tableAnnotation = null;
		for (Class model : modelClasses) {
			if (excludeClasses.contains(model)) {
				continue;
			}
			tableAnnotation = (Table) model.getAnnotation(Table.class);
			if (tableAnnotation != null) {
				String key = tableAnnotation.key();
				if (StrKit.isBlank(key))
					throw new SQLException("table not defined key");
				String tableName = tableAnnotation.tablename();
				if (StrKit.isBlank(tableName)) {
					String[] names = model.getName().toLowerCase().split("\\.");
					tableName = names[names.length - 1];
				}
				arp.addMapping(tableName, key, model);
				log.info(String.format("%s %s %s registe", tableName, key, model.getName()));
			}
		}
	}

	public AuditEntities includeAllJarsInLib(boolean includeAllJarsInLib) {
		this.includeAllJarsInLib = includeAllJarsInLib;
		return this;
	}

}
